bitkeeper revision 1.1662.1.1 (42a07145CPNIh8TprNz04Qg7x-S7Cw)
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Fri, 3 Jun 2005 15:03:33 +0000 (15:03 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Fri, 3 Jun 2005 15:03:33 +0000 (15:03 +0000)
xend cleanups from Mike Wray.
XendDomain.py:
  Add comment for domain_mem_target_set.
SrvDaemon.py:
  Use XEND_DAEMONIZE, XEND_DEBUG and XEND_DEBUGLOG.
XendRoot.py:
  Use XEND_DEBUG.
netif.py:
  Unknown domains are called "Domain-%d" % dom.
params.py:
  Add additional parameters and set some parameters from
  environment variables.
blkif.py, XendDomain.py:
  Cleanup whitespace.
XendRoot.py:
  enable_dump default is 'no'.
  enable_dump is a bool.
  Add 'true' and 'false' to get_config_bool.
XendDomainInfo.py:
  Add DOMAIN_CRASH shutdown code.
XendDomain.py:
  Simplify.
  Add domain_dumpcore.
  Move class XendDomainDict outside of class XendDomain.
  Import shutdown_reason from XendDomainInfo.
  Update comment for xen_domain.
PrettyPrint.py:
  Cleanup prettyprintstring.
SrvDir.py:
  Cleanup render_GET.
xc.c:
  Various cleanups.
Signed-off-by: Mike Wray <mike.wray@hp.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
tools/python/xen/lowlevel/xc/xc.c
tools/python/xen/web/SrvDir.py
tools/python/xen/xend/PrettyPrint.py
tools/python/xen/xend/XendDomain.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/XendRoot.py
tools/python/xen/xend/server/SrvDaemon.py
tools/python/xen/xend/server/blkif.py
tools/python/xen/xend/server/netif.py
tools/python/xen/xend/server/params.py

index c23bc461e12eef36af07054cf3e679721c9768fa..03f7468d1a7485d4f2ea4e95df5f1f4c1ba3a0ca 100644 (file)
@@ -14,6 +14,7 @@
 #include <sys/socket.h>
 #include <netdb.h>
 #include <arpa/inet.h>
+
 #include "xc_private.h"
 #include "linux_boot_params.h"
 
@@ -842,8 +843,8 @@ static PyMethodDef pyxc_methods[] = {
     { "domain_dumpcore", 
       (PyCFunction)pyxc_domain_dumpcore, 
       METH_VARARGS | METH_KEYWORDS, "\n"
-      "dump core of a domain.\n"
-      " dom [int]: Identifier of domain to be paused.\n\n"
+      "Dump core of a domain.\n"
+      " dom [int]: Identifier of domain to dump core of.\n\n"
       " corefile [string]: Name of corefile to be created.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
index fb9eb14b3c4aad559918eb2bb5cb144ba3e498f8..b168a8ef4847403ecc8c62e477711609762c9722 100644 (file)
@@ -77,19 +77,16 @@ class SrvDir(SrvBase):
         return v
 
     def render_GET(self, req):
-        try:
-            if self.use_sxp(req):
-                req.setHeader("Content-type", sxp.mime_type)
-                self.ls(req, 1)
-            else:
-                req.write('<html><head></head><body>')
-                self.print_path(req)
-                self.ls(req)
-                self.form(req)
-                req.write('</body></html>')
-            return ''
-        except Exception, ex:
-            self._perform_err(ex, "GET", req)
+        if self.use_sxp(req):
+            req.setHeader("Content-type", sxp.mime_type)
+            self.ls(req, 1)
+        else:
+            req.write('<html><head></head><body>')
+            self.print_path(req)
+            self.ls(req)
+            self.form(req)
+            req.write('</body></html>')
+        return ''
             
     def ls(self, req, use_sxp=0):
         url = req.prePathURL()
index 5fcc6e6d08dcdf998171c37d1e0c8be11a201e68..8c6d690856c619ad831d82ccecce6fca20c08d24 100644 (file)
@@ -285,15 +285,18 @@ def prettyprint(sxpr, out=sys.stdout, width=80):
         sxp.show(sxpr, out=out)
     print >> out
 
-def prettyprintstring(sxp):
-    class tmpstr:
-        def __init__(self):
-            self.str = ""
-        def write(self, str):
-            self.str = self.str + str
-    tmp = tmpstr()
-    prettyprint(sxp, out=tmp)
-    return tmp.str
+def prettyprintstring(sxp, width=80):
+    """Prettyprint an SXP form to a string.
+
+    sxpr       s-expression
+    width      maximum output width
+    """
+    io = StringIO.StringIO()
+    prettyprint(sxpr, out=io, width=width)
+    io.seek(0)
+    val = io.getvalue()
+    io.close()
+    return val
 
 def main():
     pin = sxp.Parser()
index 3fb066327f4c66e905c19b0d5bd562e484acf969..3cc234606494c757d28daa98498b02b76ba21990 100644 (file)
@@ -20,7 +20,7 @@ import sxp
 import XendRoot; xroot = XendRoot.instance()
 import XendCheckpoint
 import XendDB
-import XendDomainInfo
+from xen.xend.XendDomainInfo import XendDomainInfo, shutdown_reason
 import EventServer; eserver = EventServer.instance()
 from XendError import XendError
 from XendLogging import log
@@ -31,6 +31,13 @@ __all__ = [ "XendDomain" ]
 
 SHUTDOWN_TIMEOUT = 30
 
+class XendDomainDict(dict):
+    def get_by_name(self, name):
+        try:
+            return filter(lambda d: d.name == name, self.values())[0]
+        except IndexError, err:
+            return None
+
 class XendDomain:
     """Index of all domains. Singleton.
     """
@@ -38,15 +45,8 @@ class XendDomain:
     """Path to domain database."""
     dbpath = "domain"
 
-    class XendDomainDict(dict):
-        def get_by_name(self, name):
-            try:
-                return filter(lambda d: d.name == name, self.values())[0]
-            except IndexError, err:
-                return None
-
     """Dict of domain info indexed by domain id."""
-    domains = XendDomainDict()
+    domains = None
     
     def __init__(self):
         # Hack alert. Python does not support mutual imports, but XendDomainInfo
@@ -54,6 +54,7 @@ class XendDomain:
         # to import XendDomain from XendDomainInfo causes unbounded recursion.
         # So we stuff the XendDomain instance (self) into xroot's components.
         xroot.add_component("xen.xend.XendDomain", self)
+        self.domains = XendDomainDict()
         # Table of domain info indexed by domain id.
         self.db = XendDB.XendDB(self.dbpath)
         eserver.subscribe('xend.virq', self.onVirq)
@@ -84,6 +85,8 @@ class XendDomain:
     def xen_domain(self, dom):
         """Get info about a single domain from xc.
         Returns None if not found.
+
+        @param dom domain id
         """
         try:
             dom = int(dom)
@@ -189,7 +192,7 @@ class XendDomain:
                 continue
             log.debug('XendDomain>reap> domain died name=%s id=%s', name, id)
             if d['shutdown']:
-                reason = XendDomainInfo.shutdown_reason(d['shutdown_reason'])
+                reason = shutdown_reason(d['shutdown_reason'])
                 log.debug('XendDomain>reap> shutdown name=%s id=%s reason=%s', name, id, reason)
                 if reason in ['suspend']:
                     if dominfo and dominfo.is_terminated():
@@ -203,8 +206,8 @@ class XendDomain:
                     eserver.inject('xend.domain.exit', [name, id, reason])
                     self.domain_restart_schedule(id, reason)
             else:
-               if xroot.get_enable_dump() == 'true':
-                   xc.domain_dumpcore(dom = int(id), corefile = "/var/xen/dump/%s.%s.core"%(name,id))
+               if xroot.get_enable_dump():
+                   self.domain_dumpcore(int(id))
                eserver.inject('xend.domain.exit', [name, id, 'crash']) 
             destroyed += 1
             self.final_domain_destroy(id)
@@ -216,7 +219,7 @@ class XendDomain:
             self.reap()
         doms = self.xen_domains()
         # Add entries for any domains we don't know about.
-        for (id, d) in doms.items():
+        for id in doms.keys():
             if id not in self.domains:
                 self.domain_lookup(id)
         # Remove entries for domains that no longer exist.
@@ -326,9 +329,7 @@ class XendDomain:
 
         try:
             fd = os.open(src, os.O_RDONLY)
-
             return XendCheckpoint.restore(self, fd)
-
         except OSError, ex:
             raise XendError("can't read guest state file %s: %s" %
                             (src, ex[1]))
@@ -343,20 +344,19 @@ class XendDomain:
         self.refresh_domain(id)
         return self.domains.get(id)
 
-    def domain_lookup(self, name):
-        name = str(name)
-        dominfo = self.domains.get_by_name(name) or self.domains.get(name)
-        if dominfo:
-            return dominfo
-        try:
-            d = self.xen_domain(name)
-            if d:
-                log.info("Creating entry for unknown domain: id=%s", name)
-                dominfo = XendDomainInfo.vm_recreate(None, d)
-                self._add_domain(dominfo)
-                return dominfo
-        except Exception, ex:
-            log.exception("Error creating domain info: id=%s", name)
+    def domain_lookup(self, id):
+        name = str(id)
+        dominfo = self.domains.get_by_name(name) or self.domains.get(id)
+        if not dominfo:
+            try:
+                info = self.xen_domain(id)
+                if info:
+                    log.info("Creating entry for unknown domain: id=%s", name)
+                    dominfo = XendDomainInfo.vm_recreate(None, info)
+                    self._add_domain(dominfo)
+            except Exception, ex:
+                log.exception("Error creating domain info: id=%s", name)
+        return dominfo
 
     def domain_unpause(self, id):
         """Unpause domain execution.
@@ -595,6 +595,7 @@ class XendDomain:
             return xc.sedf_domain_get(dominfo.dom)
         except Exception, ex:
             raise XendError(str(ex))
+
     def domain_device_create(self, id, devconfig):
         """Create a new device for a domain.
 
@@ -700,11 +701,28 @@ class XendDomain:
             raise XendError(str(ex))
 
     def domain_mem_target_set(self, id, target):
+        """Set the memory target for a domain.
+
+        @param id: domain
+        @param target: memory target (in MB)
+        @return: 0 on success, -1 on error
+        """
         dominfo = self.domain_lookup(id)
         return dominfo.mem_target_set(target)
-        
 
+    def domain_dumpcore(self, id):
+        """Save a core dump for a crashed domain.
 
+        @param id: domain
+        """
+        dominfo = self.domain_lookup(id)
+        corefile = "/var/xen/dump/%s.%s.core"% (dominfo.name, dominfo.id)
+        try:
+            xc.domain_dumpcore(dom=dominfo.id, corefile=corefile)
+        except Exception, ex:
+            log.warning("Dumpcore failed, id=%s name=%s: %s",
+                        dominfo.id, dominfo.name, ex)
+        
 def instance():
     """Singleton constructor. Use this instead of the class constructor.
     """
index 0dc1aae79c7265578dd43b7655fa6d345591b0bb..05286fae207ee7a98e3cf09a350ae08baf7e1396 100644 (file)
@@ -45,11 +45,16 @@ DOMAIN_REBOOT   = 1
 """Shutdown code for suspend."""
 DOMAIN_SUSPEND  = 2
 
+"""Shutdown code for crash."""
+DOMAIN_CRASH    = 3
+
 """Map shutdown codes to strings."""
 shutdown_reasons = {
     DOMAIN_POWEROFF: "poweroff",
     DOMAIN_REBOOT  : "reboot",
-    DOMAIN_SUSPEND : "suspend" }
+    DOMAIN_SUSPEND : "suspend",
+    DOMAIN_CRASH   : "crash",
+    }
 
 """Map shutdown reasons to the message type to use.
 """
index d1bd503f8a20907486eb03d9db13e84014cdf5ca..10e560fbcc0c02ffd5235729b3efc5274c8095c8 100644 (file)
@@ -177,7 +177,10 @@ class XendRoot:
         logfile = self.get_config_value("logfile", self.logfile_default)
         loglevel = self.get_config_value("loglevel", self.loglevel_default)
         self.logging = XendLogging(logfile, level=loglevel)
-        #self.logging.addLogStderr()
+
+        from xen.xend.server import params
+        if params.XEND_DEBUG:
+            self.logging.addLogStderr()
 
     def get_logging(self):
         """Get the XendLogging instance.
@@ -241,9 +244,9 @@ class XendRoot:
 
     def get_config_bool(self, name, val=None):
         v = self.get_config_value(name, val)
-        if v in ['yes', '1', 'on', 1, True]:
+        if v in ['yes', '1', 'on', 'true', 1, True]:
             return True
-        if v in ['no', '0', 'off', 0, False]:
+        if v in ['no', '0', 'off', 'false', 0, False]:
             return False
         raise XendError("invalid xend config %s: expected bool: %s" % (name, v))
 
@@ -325,7 +328,7 @@ class XendRoot:
         return self.get_config_value('network-script', 'network')
 
     def get_enable_dump(self):
-        return self.get_config_value('enable-dump', 'false')
+        return self.get_config_bool('enable-dump', 'no')
 
     def get_vif_bridge(self):
         return self.get_config_value('vif-bridge', 'xen-br0')
index 061aa3dba79a034e3787822c893cd977703eb35b..ec418d5bea979d54ee4c4df893e44b31f0615320 100644 (file)
@@ -167,7 +167,7 @@ class Daemon:
         return pid
 
     def daemonize(self):
-        if not DAEMONIZE: return
+        if not XEND_DAEMONIZE: return
         # Detach from TTY.
         os.setsid()
 
@@ -177,16 +177,16 @@ class Daemon:
         os.close(0)
         os.close(1)
         os.close(2)
-        if DEBUG:
+        if XEND_DEBUG:
             os.open('/dev/null', os.O_RDONLY)
             # XXX KAF: Why doesn't this capture output from C extensions that
             # fprintf(stdout) or fprintf(stderr) ??
-            os.open('/var/log/xend-debug.log', os.O_WRONLY|os.O_CREAT)
+            os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT)
             os.dup(1)
         else:
             os.open('/dev/null', os.O_RDWR)
             os.dup(0)
-            os.open('/var/log/xend-debug.log', os.O_WRONLY|os.O_CREAT)
+            os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT)
 
         
     def start(self, trace=0):
@@ -308,7 +308,7 @@ class Daemon:
             servers.start()
         except Exception, ex:
             print >>sys.stderr, 'Exception starting xend:', ex
-            if DEBUG:
+            if XEND_DEBUG:
                 traceback.print_exc()
             log.exception("Exception starting xend")
             self.exit(1)
index 5a179c23a029a019e6985d67352d9aac20653e5a..903de4af1300467cb1b5bfe34b1b742b094e826b 100755 (executable)
@@ -56,7 +56,7 @@ class BlkifBackend:
 
     def openEvtchn(self):
         self.evtchn = channel.eventChannel(self.backendDomain, self.frontendDomain)
-        
+
     def getEventChannelBackend(self):
         val = 0
         if self.evtchn:
index 9d2dbc4f63d438c9580131ac09902f3c6289488c..7dd850163a91150cb5f2326fb2211a55182633c8 100755 (executable)
@@ -230,7 +230,7 @@ class NetDev(Dev):
                 vm = xd.domain_lookup(dom)
                 vmname = vm.name
             except:
-                vmname = 'DOM%d' % dom
+                vmname = 'Domain-%d' % dom
         return { 'domain': vmname,
                  'vif'   : self.get_vifname(), 
                  'mac'   : self.get_mac(),
index 5c7fdf7bad47d8bdcb8219d83a474dae1bf35009..7a2f8bdb1fa08b0a12f546777de2b1c1d1a13229 100644 (file)
@@ -1,6 +1,29 @@
-# The following parameters could be placed in a configuration file.
-XEND_PID_FILE = '/var/run/xend.pid'
-XEND_TRACE_FILE = '/var/log/xend.trace'
+import os
+
+def getenv(var, val, conv=None):
+    """Get a value from the environment, with optional conversion.
 
-XEND_USER = 'root'
+    @param var  name of environment variable
+    @param val  default value
+    @param conv conversion function to apply to env value
+    @return converted value or default
+    """
+    try:
+        v = os.getenv(var)
+        if v is None:
+            v = val
+        else:
+            print var, '=', v
+        if conv:
+            v = conv(v)
+    except:
+        v = val
+    return v
 
+# The following parameters could be placed in a configuration file.
+XEND_PID_FILE     = '/var/run/xend.pid'
+XEND_TRACE_FILE   = '/var/log/xend.trace'
+XEND_DEBUG_LOG    = '/var/log/xend-debug.log'
+XEND_USER         = 'root'
+XEND_DEBUG        = getenv("XEND_DEBUG",     0, conv=int)
+XEND_DAEMONIZE    = getenv("XEND_DAEMONIZE", not XEND_DEBUG, conv=int)